﻿// Copyright 2012 Jack Bulan (agentgeo)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using GemWorkshop.Formats.Nitro;

namespace GemWorkshop.Trainer
{
    public class TrainerLoader
    {
        private Narc trPoke, trData;
        public Pokemon[] pokemon;
        public Trainer trainer;
        //public byte[] trainerRaw, rawPoke;

        public TrainerLoader(Narc tPoke, Narc tData)
        {
            trPoke = tPoke;
            trData = tData;
        }

        public void LoadTrainer(int trainer)
        {
            //this.trainerRaw = trData.ExtractFile((uint)trainer);
            LoadData(trainer);
            LoadPokemon(trainer);
            //this.rawPoke = trPoke.ExtractFile((uint)trainer);
        }

        private void LoadPokemon(int tr)
        {
            BinaryReader br = new BinaryReader(trPoke.ExtractStream((uint)tr));

            pokemon = new Pokemon[trainer.Pokemon];
            if (trainer.UniqueMoves)
            {
                for (int i = 0; i < trainer.Pokemon; i++)
                {
                    br.ReadUInt16(); // unknown -- AI? Item?
                    pokemon[i].Level = br.ReadUInt16();
                    pokemon[i].Species = br.ReadUInt16();
                    pokemon[i].Attack1 = br.ReadUInt16();
                    pokemon[i].Attack2 = br.ReadUInt16();
                    pokemon[i].Attack3 = br.ReadUInt16();
                    pokemon[i].Attack4 = br.ReadUInt16();
                    if (trainer.UniqueItems)
                    {
                        pokemon[i].Item = br.ReadUInt16();
                    }
                }
            }
            else if (trainer.UniqueItems)
            {
                for (int i = 0; i < trainer.Pokemon; i++)
                {
                    br.ReadUInt16(); // Again, unknown.
                    pokemon[i].Level = br.ReadUInt16();
                    pokemon[i].Species = br.ReadUInt16();
                    pokemon[i].Item = br.ReadUInt16();
                }
            }
            else
            {
                for (int i = 0; i < trainer.Pokemon; i++)
                {
                    br.ReadUInt16(); // Again, unknown.
                    pokemon[i].Level = br.ReadUInt16();
                    pokemon[i].Species = br.ReadUInt16();
                }
            }

            br.Close();
            br.Dispose();
        }

        private void LoadData(int tr)
        {
            BinaryReader br = new BinaryReader(trData.ExtractStream((uint)tr));

            trainer = new Trainer();
            byte pokeFormat = br.ReadByte();
            if (pokeFormat == 0) { trainer.UniqueMoves = false; trainer.UniqueItems = false; }
            else if (pokeFormat == 1) { trainer.UniqueMoves = true; trainer.UniqueItems = false; }
            else if (pokeFormat == 2) { trainer.UniqueMoves = false; trainer.UniqueItems = true; }
            else { trainer.UniqueMoves = true; trainer.UniqueItems = true; }

            trainer.Class = br.ReadByte();

            br.BaseStream.Seek(1L, SeekOrigin.Current);
            // Don't know what second two bytes are...

            trainer.Pokemon = br.ReadByte();

            trainer.Item1 = br.ReadUInt16();
            trainer.Item2 = br.ReadUInt16();
            trainer.Item3 = br.ReadUInt16();
            trainer.Item4 = br.ReadUInt16();

            br.BaseStream.Seek(4L, SeekOrigin.Current);

            byte dBattle = br.ReadByte();
            if (dBattle == 2) trainer.DoubleBattle = true;
            else trainer.DoubleBattle = false;

            br.Close();
            br.Dispose();
        }

        public Narc TrPoke
        {
            get { return trPoke; }
        }

        public Narc TrData
        {
            get { return trData; }
        }
    }

    public struct Pokemon
    {
        public ushort Level;
        public ushort Species;
        public ushort Attack1, Attack2, Attack3, Attack4;
        public byte Form;
        public ushort Item;
    }

    public struct Trainer
    {
        public bool UniqueMoves, UniqueItems;
        public byte Class;
        public byte Pokemon;

        public ushort Item1, Item2, Item3, Item4;

        public bool DoubleBattle;
    }
}
